/*!
 * \file json_data_analyze.c
 *
 * \brief json 格式再次解析  thrift
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 *
 * \version 1.0
 * \author geyh
 * \date 2017/03/02
 *
 */

/*
 * [ 1 (version) ,   "messageName" ,  type (call, oneway, reply, exception (byte)) ,  seq id ,
 *      {
 *          "argument name" : {  " argument  type"  :  value  },
 *          "argument name" : {  " argument  type"  :  value  },
 *          "argument name" : {  " argument  type"  :  value  },
 *          ....................................................................
 *      }
 *  ]
 */

#include <frreport_comm.h>
#include "json_data_analyze.h"
#include <sys/time.h>
#include <json-c/json.h>
#include <frct_comm.h>

#define ARR_KEY_SIZE    128


#define MC_STOP     0
#define MC_VOID     1
#define MC_BOOL     2
#define MC_BYTE     3
#define MC_DOUBLE   4
#define MC_I16      6
#define MC_I32      8
#define MC_I64      10
#define MC_STRING   11
#define MC_STRUCT   12
#define MC_MAP      13
#define MC_SET      14
#define MC_LIST     15
#define MC_ENUM     16

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};
FR_STATIC int frthrift_json_list_and_set_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value);
FR_STATIC int frthrift_json_read_fields(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_object);
FR_STATIC int frthrift_json_struct_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value);

typedef int (*FRTHRIFT_JSON_MAP_KEY)(Frreport_body_data*, char*, struct json_object*);
typedef int (*FRTHRIFT_JSON_MAP_VALUE)(Frreport_body_data*, char* , struct json_object*);

/*!
 * \brief   根据类型名 获取类型值 uint8_t
 *
 * \arg     p_type_name     (类型名)
 *
 * \return  uint8_t
 *
 */
FR_STATIC uint8_t frthrift_json_get_type(const char *p_type_name)
{
    uint8_t result = MC_STOP;

    if(p_type_name == NULL)
        return MC_STOP;

    if (strlen(p_type_name) > 1) 
    {
        switch (p_type_name[0])
        {
            case 'd':
                result = MC_DOUBLE;
                break;
            case 'i':
                switch (p_type_name[1]) {
                    case '8':
                        result = MC_BYTE;
                        break;
                    case '1':
                        result = MC_I16;
                        break;
                    case '3':
                        result = MC_I32;
                        break;
                    case '6':
                        result = MC_I64;
                        break;
                    default:
                        return MC_STOP;
                }
                break;
            case 'l':
                result = MC_LIST;
                break;
            case 'm':
                result = MC_MAP;
                break;
            case 'r':
                result = MC_STRUCT;
                break;
            case 's':
                if (p_type_name[1] == 't') {
                    result = MC_STRING;
                }
                else if (p_type_name[1] == 'e') {
                    result = MC_SET;
                }
                break;
            case 't':
                result = MC_BOOL;
                break;
            default:
                return MC_STOP;
        }
    }

    return result;
}


/*!
 * \brief   thrift json string boolean 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_bool_and_str_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value)
{
    if(p_st_body_data == NULL || p_name == NULL || p_st_value == NULL)
        return FR_FAIL;

    const char *p_value = json_object_get_string(p_st_value);

    return frreport_body_l7_add_str(p_st_body_data, p_name, p_value);

}

/*!
 * \brief   thrift json integer 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_integer_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value)
{
    if(p_st_body_data == NULL || p_name == NULL || p_st_value == NULL)
        return FR_FAIL;

    long l_value = json_object_get_int64(p_st_value);

    return frreport_body_l7_add_long(p_st_body_data, p_name, l_value);

}

/*!
 * \brief   thrift json double 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_double_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value)
{
    if(p_st_body_data == NULL || p_name == NULL || p_st_value == NULL)
        return FR_FAIL;

    double db_value = json_object_get_double(p_st_value);

    return frreport_body_l7_add_double(p_st_body_data, p_name, db_value);

}

/* map 类型
{
 "map":        \\arg type
 [
   "键类型"
   ,"值类型"
   ,元素个数,
   {
     "键1": "值1",
     "键n": "值n"
   }
  ]
}
*/

/*!
 * \brief   thrift json map 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_map_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value)
{
    int i_arr_len = 0, i_map_size = 0, i_index = 0;
    struct json_object *p_st_object_tmp = NULL;
    const char *p_key_type = NULL, *p_value_type = NULL;
    char arr_key[ARR_KEY_SIZE];
    uint8_t u8_key_type = 0, u8_value_type = 0;
//    FRTHRIFT_JSON_MAP_KEY p_key_func = NULL;
    FRTHRIFT_JSON_MAP_VALUE p_value_func = NULL;
    struct json_object_iterator it;
//    p_st_array_list = json_object_get_array(p_st_value);
//    if(p_st_array_list == NULL)
//        return FR_FAIL;

    if(p_st_body_data == NULL || p_name == NULL || p_st_value == NULL)
        return FR_FAIL;

    i_arr_len = json_object_array_length(p_st_value);
    if(i_arr_len != 4)
        return FR_FAIL;

    //键类型
    p_st_object_tmp = json_object_array_get_idx(p_st_value, 0);
    if(p_st_object_tmp == NULL)
        return FR_FAIL;

    p_key_type = json_object_get_string(p_st_object_tmp);
    u8_key_type = frthrift_json_get_type(p_key_type);
    if(u8_key_type == MC_STOP)
        return FR_FAIL;

    //值类型
    p_st_object_tmp = json_object_array_get_idx(p_st_value, 1);
    if(p_st_object_tmp == NULL)
        return FR_FAIL;

    p_value_type = json_object_get_string(p_st_object_tmp);
    u8_value_type = frthrift_json_get_type(p_value_type);
    if(u8_value_type == MC_STOP)
        return FR_FAIL;

    //元素个数
    p_st_object_tmp = json_object_array_get_idx(p_st_value, 2);
    if(p_st_object_tmp == NULL)
        return FR_FAIL;

    i_map_size = json_object_get_int(p_st_object_tmp);
    if(i_map_size == 0)
    {
        snprintf(arr_key, ARR_KEY_SIZE, "%s.map", p_name);
        frreport_body_l7_add_str(p_st_body_data, arr_key, "null");
        return FR_SUCC;
    }
//
//    //设置 key 解析函数
//    switch (u8_key_type)
//    {
//        case MC_BOOL:
//        case MC_STRING:
//            p_key_func = (FRTHRIFT_JSON_MAP_KEY) frthrift_json_bool_and_str_report;
//        break;
//
//        case MC_BYTE:
//        case MC_I16:
//        case MC_I32:
//        case MC_I64:
//            p_key_func = (FRTHRIFT_JSON_MAP_KEY) frthrift_json_integer_report;
//            break;
//
//        case MC_DOUBLE:
//            p_key_func = (FRTHRIFT_JSON_MAP_KEY) frthrift_json_double_report;
//            break;
//
//        case MC_MAP:
//            p_key_func = (FRTHRIFT_JSON_MAP_KEY) frthrift_json_map_report;
//            break;
//
//        case MC_SET:
//        case MC_LIST:
//            p_key_func = (FRTHRIFT_JSON_MAP_KEY) frthrift_json_list_and_set_report;
//            break;
//
//        case MC_STRUCT:
//            p_key_func = (FRTHRIFT_JSON_MAP_KEY) frthrift_json_struct_report;
//            break;
//
//        default:
//            return FR_FAIL;
//    }

    //设置value解析函数
    switch (u8_value_type)
    {
        case MC_BOOL:
        case MC_STRING:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_bool_and_str_report;
            break;

        case MC_BYTE:
        case MC_I16:
        case MC_I32:
        case MC_I64:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_integer_report;
            break;

        case MC_DOUBLE:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_double_report;
            break;

        case MC_MAP:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_map_report;
            break;

        case MC_SET:
        case MC_LIST:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_list_and_set_report;
            break;

        case MC_STRUCT:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_struct_report;
            break;

        default:
            return FR_FAIL;
    }

    //值
    p_st_object_tmp = json_object_array_get_idx(p_st_value, 3);
    if(p_st_object_tmp == NULL)
        return FR_FAIL;

    i_map_size = json_object_object_length(p_st_object_tmp);
    if(i_map_size == 0)
    {
        snprintf(arr_key, ARR_KEY_SIZE, "%s.map", p_name);
        frreport_body_l7_add_str(p_st_body_data, arr_key, "null");
        return FR_SUCC;

    }

    snprintf(arr_key,ARR_KEY_SIZE, "%s.map.key.type", p_name);
    frreport_body_l7_add_str(p_st_body_data, arr_key, p_key_type);

    // "key" : value
    it = json_object_iter_begin(p_st_object_tmp);
    while (i_index < i_map_size)
    {
        p_st_object_tmp = (struct json_object *)json_object_iter_peek_value(&it);
        if(p_st_object_tmp == NULL)
            return FR_FAIL;

        i_index++;
        // KEY上报
        snprintf(arr_key, ARR_KEY_SIZE, "%s.map.%d.key", p_name, i_index);
        frreport_body_l7_add_str(p_st_body_data, arr_key,
                json_object_iter_peek_name(&it));

        // value 上报
        snprintf(arr_key, ARR_KEY_SIZE, "%s.map.%d.value", p_name, i_index);
        if(p_value_func(p_st_body_data, arr_key, p_st_object_tmp) == FR_FAIL)
            return FR_FAIL;

        json_object_iter_next(&it);

    }

    snprintf(arr_key, ARR_KEY_SIZE, "%s.map.size", p_name);
    frreport_body_l7_add_int(p_st_body_data, arr_key, i_map_size);

    return FR_SUCC;

}

/*
{
  "set/lst": ["值类型",
    元素个数,
    "ele1",
    "ele2",
    "elen"
  ]
},
 */
/*!
 * \brief   thrift json set/list 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_list_and_set_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value)
{
//    struct array_list* *p_st_array_list = NULL;
    int i_arr_len = 0, i_lst_size = 0;
    struct json_object *p_st_object_tmp = NULL;
    const char *p_value_type = NULL;
    char arr_key[ARR_KEY_SIZE];
    int i_index = 0, i_tmp = 0;
    uint8_t u8_value_type = 0;
    FRTHRIFT_JSON_MAP_VALUE p_value_func = NULL;

    if(p_st_body_data == NULL || p_name == NULL || p_st_value == NULL)
        return FR_FAIL;

//    p_st_array_list = json_object_get_array(p_st_object);
//    if(p_st_array_list == NULL)
//        return FR_FAIL;

    i_arr_len = json_object_array_length(p_st_value);
    if(i_arr_len < 2)
        return FR_FAIL;

    //值类型
    p_st_object_tmp = json_object_array_get_idx(p_st_value, 0);
    if(p_st_object_tmp == NULL)
        return FR_FAIL;

    p_value_type = json_object_get_string(p_st_object_tmp);
    u8_value_type = frthrift_json_get_type(p_value_type);
    if(u8_value_type == MC_STOP)
        return FR_FAIL;

    switch (u8_value_type)
    {
        case MC_BOOL:
        case MC_STRING:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_bool_and_str_report;
            break;

        case MC_BYTE:
        case MC_I16:
        case MC_I32:
        case MC_I64:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_integer_report;
            break;

        case MC_DOUBLE:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_double_report;
            break;

        case MC_MAP:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_map_report;
            break;

        case MC_SET:
        case MC_LIST:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_list_and_set_report;
            break;

        case MC_STRUCT:
            p_value_func = (FRTHRIFT_JSON_MAP_VALUE) frthrift_json_struct_report;
            break;

        default:
            return FR_FAIL;
    }

    //元素个数
    p_st_object_tmp = json_object_array_get_idx(p_st_value, 1);
    if(p_st_object_tmp == NULL)
        return FR_FAIL;

    //如果list为空
    i_lst_size = json_object_get_int(p_st_object_tmp);
    if(i_lst_size == 0)
    {
        snprintf(arr_key, ARR_KEY_SIZE, "%s.list", p_name);
        return frreport_body_l7_add_str(p_st_body_data, arr_key, "null");
    }

    //值
    i_tmp = 1;

    while (i_lst_size)
    {
        i_index++;
        i_tmp++;
        snprintf(arr_key, ARR_KEY_SIZE, "%s.list.%d", p_name, i_index);
        p_st_object_tmp = json_object_array_get_idx(p_st_value, i_tmp);
        if(p_st_object_tmp == NULL)
            return FR_FAIL;

        if(p_value_func(p_st_body_data, arr_key, p_st_object_tmp) == FR_FAIL)
            return FR_FAIL;

        i_lst_size--;
    }

    snprintf(arr_key, ARR_KEY_SIZE, "%s.list.size", p_name);
    frreport_body_l7_add_int(p_st_body_data, arr_key, i_index);

    return FR_SUCC;

}

/*
  "rec": {
    "成员编号": {
      "成员类型": "成员值"
    },
    ...
  }
 */
/*!
 * \brief   thrift json struct 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_struct_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value)
{
    if(p_st_body_data == NULL || p_name == NULL || p_st_value == NULL)
        return FR_FAIL;

    char arr_key[ARR_KEY_SIZE];
    snprintf(arr_key, ARR_KEY_SIZE, "%s.struct", p_name);

    return frthrift_json_read_fields(p_st_body_data, arr_key, p_st_value);

    return FR_SUCC;

}


/*
 * "argument name" : {  " argument  type"  :  value  }
 */
/*!
 * \brief   thrift json 值 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_value_report(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_value)
{
    struct json_object_iterator it;
    const char *p_type = NULL;
    struct json_object *p_json_value = NULL;
    uint8_t u8_type = 0;

    if(p_st_body_data == NULL || p_name == NULL || p_st_value == NULL)
        return FR_FAIL;

    // value  {  " argument  type"  :  value  }
    it = json_object_iter_begin(p_st_value);

    p_type = json_object_iter_peek_name(&it);
    if(p_type == NULL)
        return FR_FAIL;

    p_json_value = json_object_iter_peek_value(&it);
    if(p_json_value == NULL)
        return FR_FAIL;

    u8_type = frthrift_json_get_type(p_type);

    switch (u8_type)
    {
        case MC_BOOL:
        case MC_STRING:
            return frthrift_json_bool_and_str_report(p_st_body_data, p_name, p_json_value);

        case MC_BYTE:
        case MC_I16:
        case MC_I32:
        case MC_I64:
            return frthrift_json_integer_report(p_st_body_data, p_name, p_json_value);

        case MC_DOUBLE:
            return frthrift_json_double_report(p_st_body_data, p_name, p_json_value);

        case MC_MAP:
            return frthrift_json_map_report(p_st_body_data, p_name, p_json_value);
        case MC_SET:
        case MC_LIST:
            return frthrift_json_list_and_set_report(p_st_body_data, p_name, p_json_value);

        case MC_STRUCT:
            return frthrift_json_struct_report(p_st_body_data, p_name, p_json_value);

        default:
            return FR_FAIL;
    }

    return FR_SUCC;

}


/*
 *      {
 *          "argument name" : {  " argument  type"  :  value  },
 *          "argument name" : {  " argument  type"  :  value  },
 *          "argument name" : {  " argument  type"  :  value  },
 *          ....................................................................
 *      }
 */
/*!
 * \brief   thrift json 参数 信息上报
 *
 * \arg     p_st_body_data          上报链表
 *          p_name                  上报值名
 *          p_st_value              内容
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
FR_STATIC int frthrift_json_read_fields(Frreport_body_data *p_st_body_data, char *p_name, struct json_object *p_st_object)
{
    struct json_object *p_st_value = NULL;
    struct json_object_iterator it, it_end;
    const char *p_id = NULL;
    char arr_key[ARR_KEY_SIZE];
    int i_index = 0;

    if(p_st_body_data == NULL || p_name == NULL || p_st_object == NULL)
        return FR_FAIL;

    /*
     *          "argument name" : {  " argument  type"  :  value  },
     *          "argument name" : {  " argument  type"  :  value  },
     *          "argument name" : {  " argument  type"  :  value  },
     */

    it = json_object_iter_begin(p_st_object);
    it_end = json_object_iter_end(p_st_object);

    while (!json_object_iter_equal(&it, &it_end))
    {
        i_index++;
        //arg name
        p_id = json_object_iter_peek_name(&it);
        if(p_id == NULL)
            return FR_FAIL;

        //arg value
        p_st_value = json_object_iter_peek_value(&it);
        if(p_st_value == NULL)
            return FR_FAIL;

        // {  " argument  type"  :  value  }
        snprintf(arr_key, ARR_KEY_SIZE, "%s.%d", p_name, i_index);
        frthrift_json_value_report(p_st_body_data, arr_key, p_st_value);

        json_object_iter_next(&it);

    }

    snprintf(arr_key, ARR_KEY_SIZE, "%s.size", p_name);
    frreport_body_l7_add_int(p_st_body_data, arr_key, i_index);

    return FR_SUCC;

}

/*!
 * \brief   thrift json double 信息上报
 *
 * \arg     p_data_in               入力参数
 *          p_st_body_data          上报链表
 *          p_st_private            私有数据
 *          i_use_request           request/response
 *          p_prefix                前缀
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
int frthrift_json_analyze(char *p_data_in, Frreport_body_data *p_st_body_data, L7session_json_private *p_st_private
                          , int i_use_request, char *p_prefix)
{
    struct json_object *p_st_object = NULL;
    struct json_object *p_st_object_tmp = NULL;
//    struct array_list *p_st_array_list = NULL;
    char arr_key[ARR_KEY_SIZE];
    int i_arr_len = 0;
    int i_version = 0, i_msg_type = 0;
    const char *p_func = NULL;

    if(p_data_in == NULL || p_st_body_data == NULL || p_st_private == NULL || p_prefix == NULL)
        return FR_FAIL;
    /*
     * 1: thrift version
     * 2: thrift func
     * 3: thrift type
     * 4: thrift seq id
     */
    p_st_object = json_tokener_parse(p_data_in);
    if(p_st_object == NULL)
        goto ERROR;

//    p_st_array_list = json_object_get_array(p_st_object);
//    if(p_st_array_list == NULL)
//        goto ERROR;

    i_arr_len = json_object_array_length(p_st_object);
    if(i_arr_len < 4)
        goto ERROR;

    p_st_object_tmp = json_object_array_get_idx(p_st_object, 0);
    if(p_st_object_tmp == NULL)
        goto ERROR;

    i_version = json_object_get_int(p_st_object_tmp);

    snprintf(arr_key, ARR_KEY_SIZE, "%s.version", p_prefix);
    frreport_body_l7_add_int(p_st_body_data, arr_key, i_version);

    if(i_use_request)
    {
        //获取函数名  不用释放
        p_st_object_tmp = json_object_array_get_idx(p_st_object, 1);
        if(p_st_object_tmp == NULL)
            goto ERROR;

        p_func = json_object_get_string(p_st_object_tmp);
        snprintf(arr_key, ARR_KEY_SIZE, "%s.func", p_prefix);
        frreport_body_l7_add_str(p_st_body_data, arr_key, p_func);
        frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_TRANS_TITLE, p_func);

        //message type
        p_st_object_tmp = json_object_array_get_idx(p_st_object, 2);
        if(p_st_object_tmp == NULL)
            goto ERROR;

        i_msg_type = json_object_get_int(p_st_object_tmp);

        //one way
        if(i_msg_type == 4)
        {
            if(frreport_body_l7_add_int(p_st_body_data, APM_REPORT_KEY_REQ_ISRESPREQUIRED, 0) == FR_FAIL)
                goto ERROR;
        }
        else if(i_msg_type == 1)
        {
            if(frreport_body_l7_add_int(p_st_body_data, APM_REPORT_KEY_REQ_ISRESPREQUIRED, 1) == FR_FAIL)
                goto ERROR;
        }
        else
        {
            goto ERROR;
        }

        //seq id
        p_st_object_tmp = json_object_array_get_idx(p_st_object, 3);
        if(p_st_object_tmp == NULL)
            goto ERROR;

        p_st_private->i_seq_id = json_object_get_int(p_st_object_tmp);

        //key
        p_st_object_tmp = json_object_array_get_idx(p_st_object, 4);
        if(p_st_object_tmp == NULL)
            return FR_SUCC;

        snprintf(arr_key, ARR_KEY_SIZE, "%s.arg", p_prefix);
        if(frthrift_json_read_fields(p_st_body_data, arr_key, p_st_object_tmp) == FR_FAIL)
            goto ERROR;

    }
    else
    {
        //message type
        p_st_object_tmp = json_object_array_get_idx(p_st_object, 2);
        if (p_st_object_tmp == NULL)
            goto ERROR;

        i_msg_type = json_object_get_int(p_st_object_tmp);

        //expect err msg
        if (i_msg_type == 2)
        {
            frreport_body_l7_add_long(p_st_body_data, APM_REPORT_KEY_RESP_CODE, 0);
        }
        else if (i_msg_type == 3)
        {
            frreport_body_l7_add_long(p_st_body_data, APM_REPORT_KEY_RESP_CODE, 1);
        }
        else
        {
            goto ERROR;
        }

        //获取相关内容
        p_st_object_tmp = json_object_array_get_idx(p_st_object, 3);
        if (p_st_object_tmp == NULL)
            goto ERROR;

        p_st_private->i_seq_id = json_object_get_int(p_st_object_tmp);

        p_st_object_tmp = json_object_array_get_idx(p_st_object, 4);
        if (p_st_object_tmp == NULL)
            return FR_SUCC;

        snprintf(arr_key, ARR_KEY_SIZE, "%s.return", p_prefix);
        if(frthrift_json_read_fields(p_st_body_data, arr_key, p_st_object_tmp) == FR_FAIL)
            goto ERROR;

    }

    json_object_put(p_st_object);
    return FR_SUCC;

ERROR:

    json_object_put(p_st_object);
    return FR_FAIL;

}

/*!
 * \brief   thrift json d格式判断
 *
 * \arg     p_data_in               入力参数
 *
 * \return  FR_YES:成功
 *          FR_NO:失败
 *
 */
int frthrift_data_detect(char *p_data_in)
{
    struct json_object *p_st_object = NULL;
    struct json_object *p_st_object_tmp = NULL;
//    struct array_list* *p_st_array_list = NULL;
    int i_arr_len = 0;
    int i_version = 0, i_msg_type = 0, i_seq_id = 0;
    const char *p_func = NULL;

    if(p_data_in == NULL || p_data_in[0] != '[')
        return FR_NO;
    /*
     * 1: thrift version
     * 2: thrift func
     * 3: thrift type
     * 4: thrift seq id
     */
    p_st_object = json_tokener_parse(p_data_in);
    if(p_st_object == NULL)
        goto ERROR;

//    p_st_array_list = json_object_get_array(p_st_object);
//    if(p_st_array_list == NULL)
//        goto ERROR;

    i_arr_len = json_object_array_length(p_st_object);
    if(i_arr_len < 4)
        goto ERROR;

    p_st_object_tmp = json_object_array_get_idx(p_st_object, 0);
    if(p_st_object_tmp == NULL)
        goto ERROR;

    i_version = json_object_get_int(p_st_object_tmp);
    if(i_version == 0)
        goto ERROR;

    //获取函数名  不用释放
    p_st_object_tmp = json_object_array_get_idx(p_st_object, 1);
    if(p_st_object_tmp == NULL)
        goto ERROR;

    p_func = json_object_get_string(p_st_object_tmp);
    if(p_func == NULL)
        goto ERROR;

    //message type
    p_st_object_tmp = json_object_array_get_idx(p_st_object, 2);
    if(p_st_object_tmp == NULL)
        goto ERROR;

    i_msg_type = json_object_get_int(p_st_object_tmp);
    if(i_msg_type > 4 || i_msg_type < 1)
        goto ERROR;

    //seq id
    p_st_object_tmp = json_object_array_get_idx(p_st_object, 3);
    if(p_st_object_tmp == NULL)
        goto ERROR;

    i_seq_id = json_object_get_int(p_st_object_tmp);
    if(i_seq_id < 0)
        goto ERROR;

    json_object_put(p_st_object);
    return FR_YES;

ERROR:

    json_object_put(p_st_object);
    return FR_NO;

}

/*!
 * \brief   thrift json 异步信息添加
 *
 * \arg     p_st_privata         私有数据
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
int frjson_thrift_data_add(L7session_json_private *p_st_privata)
{
    Frlist_header *p_st_head = NULL;
    Frlist_node *p_st_node = 0;
    thrift_data *p_st_thrift = NULL;

    if(p_st_privata == NULL)
        return FR_FAIL;

    if(p_st_privata->p_private_data == NULL)
        p_st_privata->p_private_data = frlist_create();

    p_st_head = (Frlist_header *)p_st_privata->p_private_data;

    p_st_thrift = (thrift_data *) frmalloc(sizeof(thrift_data));
    if(p_st_thrift == NULL)
        return FR_FAIL;

    p_st_thrift->i_seq_id = p_st_privata->i_seq_id;
    p_st_thrift->p_report_comm = p_st_privata->p_report_comm;
    p_st_privata->p_report_comm = NULL;

    p_st_thrift->p_report_req = p_st_privata->p_report_req;
    p_st_privata->p_report_req = NULL;

    memcpy(&p_st_thrift->st_l4_trans, &p_st_privata->st_l4_trans, sizeof(L4_transaction));
    memset(&p_st_privata->st_l4_trans, 0x00, sizeof(L4_transaction));

    p_st_node = frlist_node_create(p_st_thrift);
    frlist_push(p_st_head, p_st_node);

    return FR_SUCC;

}

/*!
 * \brief   thrift_data 链表销毁
 *
 * \arg     node    thrift_data 链表节点
 *
 * \return  void
 *
 */
void frthritf_list_node_free(Frlist_node *node)
{
    thrift_data *p_st_thrift_data = NULL;

    if(node && node->data)
    {
        p_st_thrift_data = (thrift_data *)node->data;

        if(p_st_thrift_data->p_report_comm)
            frreport_body_l7list_free(&p_st_thrift_data->p_report_comm);

        if(p_st_thrift_data->p_report_req)
            frreport_body_l7list_free(&p_st_thrift_data->p_report_req);

        frfree(p_st_thrift_data);
    }

    return;
}

/*!
 * \brief   thrift 链表中查找函数 异步对应 seqid
 *
 * \arg     p_st_node       数据节点
 *          p_data          比较数据
 *
 * \return  1 没找到
 *          0 查找到
 *
 */
FR_STATIC int __frthrift_asyc_req_find(Frlist_node *p_st_node, const void *p_data)
{
    thrift_data *p_st_thrift_data = NULL;
    L7session_json_private *p_st_privata = (L7session_json_private *)p_data;

    if(p_st_node == NULL || p_st_node->data == NULL || p_st_privata == NULL)
        return 1;

    p_st_thrift_data = (thrift_data *)p_st_node->data;

    if(p_st_thrift_data->i_seq_id == p_st_privata->i_seq_id)
        return 0;

    return 1;

}

/*!
 * \brief   thrift json 异步信息添加
 *
 * \arg     p_st_privata         私有数据
 *
 * \return  FR_SUCC:成功
 *          FR_FAIL:失败
 *
 */
int frjson_thrift_data_set(L7session_json_private *p_st_privata)
{
    Frlist_header *p_st_head = NULL;
    Frlist_node *p_st_node = 0;
    thrift_data *p_st_thrift = NULL;

    if(p_st_privata == NULL || p_st_privata->p_private_data == NULL)
        return FR_FAIL;

    p_st_head = (Frlist_header *)p_st_privata->p_private_data;

    p_st_node = frlist_find(p_st_head, p_st_privata, __frthrift_asyc_req_find);
    if(p_st_node == NULL)
        return FR_FAIL;

    p_st_thrift = (thrift_data *)p_st_node->data;

    if(p_st_privata->p_report_comm)
        return FR_FAIL;

    p_st_privata->p_report_comm = p_st_thrift->p_report_comm;
    p_st_privata->p_report_req = p_st_thrift->p_report_req;

    //st_request_time_first_byte
    p_st_privata->st_l4_trans.st_request_time_first_byte.tv_sec = p_st_thrift->st_l4_trans.st_request_time_first_byte.tv_sec;
    p_st_privata->st_l4_trans.st_request_time_first_byte.tv_usec = p_st_thrift->st_l4_trans.st_request_time_first_byte.tv_usec;

    //st_request_time
    p_st_privata->st_l4_trans.st_request_time.tv_sec = p_st_thrift->st_l4_trans.st_request_time.tv_sec;
    p_st_privata->st_l4_trans.st_request_time.tv_usec = p_st_thrift->st_l4_trans.st_request_time.tv_usec;

    frlist_node_apart(p_st_head, p_st_node);
    frfree(p_st_thrift);
    frfree(p_st_node);

    return FR_SUCC;

}

/*!
 * \brief   thrift_data 链表销毁
 *
 * \arg     node    thrift_data 链表节点
 *
 * \return  void
 *
 */
void frjson_thritf_list_node_free(Frlist_node *node)
{
    thrift_data *p_st_thrift_data = NULL;

    if(node && node->data)
    {
        p_st_thrift_data = (thrift_data *)node->data;

        if(p_st_thrift_data->p_report_comm)
            frreport_body_l7list_free(&p_st_thrift_data->p_report_comm);

        if(p_st_thrift_data->p_report_req)
            frreport_body_l7list_free(&p_st_thrift_data->p_report_req);

        frfree(p_st_thrift_data);
    }

    return;
}

/*!
 * \brief   thrift_data 链表销毁
 *
 * \arg     pp_private_data    再次解析 私有数据销毁
 *
 * \return  void
 *
 */
void frjson_thrift_private_free(void **pp_private_data)
{
    Frlist_header *p_st_head = NULL;

    if(pp_private_data == NULL || *pp_private_data == NULL)
        return;

    p_st_head = (Frlist_header *)*pp_private_data;

    frlist_destroy(p_st_head, frjson_thritf_list_node_free);
    *pp_private_data = NULL;
}


/*!
 * \brief   thrift json 方向判断
 *
 * \arg     p_data_in               入力参数
 *
 * \return  FR_YES:成功
 *          FR_NO:失败
 *
 */
int frthrift_direction_detect(char *p_data_in)
{
    struct json_object *p_st_object = NULL;
    struct json_object *p_st_object_tmp = NULL;
    int i_arr_len = 0;
    int i_ret = 0, i_msg_type = 0;


    /*
     * 1: thrift version
     * 2: thrift func
     * 3: thrift type
     * 4: thrift seq id
     */
    p_st_object = json_tokener_parse(p_data_in);
    if(p_st_object == NULL)
        goto ERROR;

    //    p_st_array_list = json_object_get_array(p_st_object);
    //    if(p_st_array_list == NULL)
    //        goto ERROR;

    i_arr_len = json_object_array_length(p_st_object);
    if(i_arr_len < 4)
        goto ERROR;

    //message type
    p_st_object_tmp = json_object_array_get_idx(p_st_object, 2);
    if(p_st_object_tmp == NULL)
        goto ERROR;

    i_msg_type = json_object_get_int(p_st_object_tmp);
    if(i_msg_type > 4 || i_msg_type < 1)
        goto ERROR;

    if(i_msg_type == 1 || i_msg_type == 4)
        i_ret = FR_DIRECT_CLIENT2SRV;
    else if(i_msg_type == 2 || i_msg_type == 3)
        i_ret = FR_DIRECT_SRV2CLIENT;
    else
        i_ret = FR_DIRECT_UNKNOWN;

    json_object_put(p_st_object);

    return i_ret;

ERROR:

    json_object_put(p_st_object);
    return FR_DIRECT_UNKNOWN;

}


